﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BestEasy.CMS.Services.Interfaces.Security;
using BestEasy.CMS.Services.Messaging.Request.Security;
using BestEasy.CMS.Services.Messaging.Response;
using BestEasy.CMS.Services.ViewModels.Security;
using BestEasy.CMS.Services.Mapping;
using BestEasy.CMS.Models.Security;

using BestEasy.Core.UnitOfWork;
using BestEasy.Core;
using BestEasy.Core.Caching;
using BestEasy.Core.Pageing;

namespace BestEasy.CMS.Services.Implementations.Security
{
    public class RoleService : IRoleService
    {
        #region 属性
        private readonly IRoleRepository _roleRepository;
        private readonly IUnitOfWork _unitOfWork;
        private readonly ICacheManager _cacheManager;
        #endregion

        #region  构造函数
        public RoleService(IRoleRepository userRepository, IUnitOfWork unitOfWork, ICacheManager cacheManager)
        {
            _roleRepository = userRepository;
            _unitOfWork = unitOfWork;
            _cacheManager = cacheManager;
        }
        #endregion

        #region 方法
        public ResponseBase Save(RoleView view, SaveType type)
        {
            if (view == null)
                throw new ArgumentNullException(nameof(view));
            var response = new ResponseBase();
            try
            {
                var entity = view.ToEntity<Role, RoleView>();
                if (type == SaveType.Update)
                    _roleRepository.Update(entity);
                else
                    _roleRepository.Insert(entity);
                _unitOfWork.Commit();
                response.IsSuccess = true;
            }
            catch (BestEasyException ex)
            {
                response.IsSuccess = false;
                response.Message = ex.Message;
            }
            return response;
        }

        public async Task<ResponseBase> SaveAsync(RoleView view, SaveType type)
        {
            if (view == null)
                throw new ArgumentNullException(nameof(view));

            var response = new ResponseBase();
            var entity = view.ToEntity<Role, RoleView>();
            switch (type)
            {
                case SaveType.Insert:
                    var obj = await _roleRepository.InsertAsync(entity);
                    var flag = obj != null && Convert.ToInt32(obj) > 0;
                    response.IsSuccess = flag;
                    response.Message = flag ? "保存成功！" : "保存失败！";
                    break;
                case SaveType.Update:
                    var row = await _roleRepository.UpdateAsync(entity);
                    var flag1 = row > 0;
                    response.IsSuccess = flag1;
                    response.Message = flag1 ? "保存成功！" : "保存失败！";
                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(type), type, null);
            }
            return response;
        }

        public ResponseBase Delete(long id)
        {
            var response = new ResponseBase();
            if (id == 0)
                return response;
            var role = _roleRepository.GetById(id);
            if (role == null)
                return response;
            if (role.IsSystemRole)
                throw new BestEasyException($"无法删除系统角色（{role.RoleName}）");
            var result = _roleRepository.Delete(id);
            return new ResponseBase { IsSuccess = result > 0 };
        }

        public ResponseBase Save(SaveRoleRequest request)
        {
            if (request == null)
                throw new ArgumentNullException(nameof(request));
            if (request.RoleView == null)
                throw new ArgumentNullException(nameof(request.RoleView));
            if (request.ResourceView == null)
                throw new ArgumentNullException(nameof(request.ResourceView));
            var response = new ResponseBase();
            try
            {
                //保存角色信息
                _roleRepository.Insert(request.RoleView.ToEntity<Role, RoleView>());



            }
            catch (BestEasyException ex)
            {
                response.IsSuccess = false;
                response.Message = ex.Message;
            }
            return response;
        }

        public ResponseBase TakeDelete(long id)
        {
            var response = new ResponseBase();
            if (id == 0)
                return response;
            var role = _roleRepository.GetById(id);
            if (role == null)
                return response;
            if (role.IsSystemRole)
                throw new BestEasyException($"无法删除系统角色（{role.RoleName}）");
            try
            {
                var result = _roleRepository.UpdateMany().Where(p => p.Id == id).OnlyFields(p => p.IsDel).Execute(new Role { IsDel = true });
                response.IsSuccess = result > 0;
            }
            catch (BestEasyException ex)
            {
                response.IsSuccess = false;
                response.Message = ex.Message;
            }
            _cacheManager.Remove(CacheKeyHelper.BestEasyCacheRolePatternKey);
            return response;
        }

        public GetListResponse<RoleView> GetAll()
        {
            var response = new GetListResponse<RoleView>();
            IList<RoleView> result;
            if (CacheHelper.IsStart)
            {
                result = GetRoleViewByCache();
                if (result == null || !result.Any())
                {
                    response.Message = "暂无数据！";
                    return response;
                }
                response.IsSuccess = true;
                response.Message = "获取成功！";
                response.Views = result;
                return response;
            }
            IList<Role> entitys = _roleRepository.Query().Where(p => !p.IsDel).ToList();
            result = entitys.ToViews<Role, RoleView>();
            if (result == null || !result.Any())
            {
                response.Message = "暂无数据！";
                return response;
            }
            response.IsSuccess = true;
            response.Message = "获取成功！";
            response.Views = result;
            return response;
        }

        public GetSingleResponse<RoleView> GetById(long id)
        {
            var response = new GetSingleResponse<RoleView>();
            if (id == 0)
                return response;
            var result = _roleRepository.GetById(id);
            if (result != null && !result.IsDel)
            {
                response.IsSuccess = true;
                response.View = result.ToView<Role, RoleView>();
            }
            return response;
        }

        public GetPageResponse<RoleView> GetByPage(Paged page)
        {
            if (page == null)
                throw new ArgumentNullException(nameof(page));

            var response = new GetPageResponse<RoleView>();
            var result = _roleRepository.Query().Where(p => !p.IsDel).ToPage(page.PageIndex, page.PageSize);
            if (result.Items.Any())
            {
                response.Message = "获取成功！";
                response.IsSuccess = true;
                response.Pages = result.ToPageView<Role, RoleView>();
            }
            return response;
        }

        public GetPageResponse<RoleView> GetRoles(GetRolePageRequest request)
        {
            if (request == null)
                throw new ArgumentNullException(nameof(request));

            var response = new GetPageResponse<RoleView>();
            var result = _roleRepository.Query().Where(p => !p.IsDel).ToPage(request.Paged.PageIndex, request.Paged.PageSize);
            if (!result.Items.Any())
            {
                response.Message = "暂无数据!";
                return response;
            }
            response.Message = "获取成功！";
            response.IsSuccess = true;
            response.Pages = result.ToPageView<Role, RoleView>();
            return response;
        }

        public bool RoleNameExists(RoleNameExistsRequest request)
        {
            if (request == null)
                throw new ArgumentNullException(nameof(request));

            if (CacheHelper.IsStart)
            {
                var result = GetRoleViewByCache();
                if (request.Id == null)
                    return result.Any(p => p.RoleName == request.Name);
                var count1 = result.Count(p => p.RoleName == request.Name && p.Id == request.Id);
                if (count1 == 1)
                    return false;
                if (count1 == 0)
                    return result.Any(p => p.RoleName == request.Name);
            }
            if (request.Id == null)
                return _roleRepository.Query().Any(p => p.RoleName == request.Name);
            var count2 = _roleRepository.Query().Count(p => p.RoleName == request.Name && p.Id == request.Id);
            if (count2 == 1)
                return false;
            if (count2 == 0)
                return _roleRepository.Query().Any(p => p.RoleName == request.Name);
            return false;
        }

        #endregion

        /// <summary>
        /// 在缓存中获取资源数据
        /// </summary>
        /// <returns></returns>
        private IList<RoleView> GetRoleViewByCache()
        {
            return _cacheManager.Get(CacheKeyHelper.BestEasyCacheRolePatternKey, () =>
            {
                var entitys = _roleRepository.Query().Where(p => !p.IsDel).ToList();
                var result = entitys.ToViews<Role, RoleView>();
                return result;
            });
        }
    }
}
